package com.next

import grails.transaction.Transactional
import org.springframework.security.access.annotation.Secured

import java.text.SimpleDateFormat

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class ContactController
{

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE", appRegister: "POST", appLogin: "POST"]

    def springSecurityService
    def exportService
    def subscribeService

    def index(Integer max)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def contactList = Contact.findAll("from Contact where user.username = '${username}' order by modifiedDate desc", [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Contact.executeQuery("select count(id) from Contact where user.username = '${username}'")

        respond contactList, model: [contactCount: count[0]]
    }

    def show(Contact contact)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        def addressList = Address.findAll("from Address where contact.id = ?", [contact.id])
        def noteList = Note.findAll("from Note where contact.id = ?", [contact.id])
        def attachmentList = Attachment.findAll("from Attachment where contact.id = ?", [contact.id])
        def teamList = ContactTeam.findAll("from ContactTeam where contact.id = ?", [contact.id])
        def flexFieldInstanceList = FlexFieldInstance.findAll("from FlexFieldInstance where contact.id = ?", [contact.id])
        def appointmentList = Activity.findAll("from Activity where contact.id = ? and type.id = ?", [contact.id, ActivityType.find("from ActivityType where name = 'Appointment'")?.id])
        def taskList = Activity.findAll("from Activity where contact.id = ? and type.id = ?", [contact.id, ActivityType.find("from ActivityType where name = 'Task'")?.id])
        def follow = Follow.findByContactAndUser(contact, user)
        respond contact, model: [addressList: addressList, noteList: noteList, attachmentList: attachmentList, teamList: teamList, flexFieldInstanceList: flexFieldInstanceList, appointmentList: appointmentList, taskList: taskList, teamName: 'contactTeam', follow: follow]
    }

    def create()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        Company company = Company.findAll()[0]
        Boolean enableTerritory = company.enableContactTerritory
        if (company.enableAccountTerritory && company.inheritanceAccountTerritory)
        {
            enableTerritory = false
        }
        respond new Contact(params), model: [enableTerritory: enableTerritory, user: user]
    }

    @Transactional
    def save(Contact contact)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (contact == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (contact.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond contact.errors, model: [user: user], view: 'create'
            return
        }

        contact.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'contact.label',
                                                                                        default: 'Contact'), contact
                    .id])
                redirect contact
                // redirect action: "create"
            }
            '*' { respond contact, [status: CREATED] }
        }
    }

    @Transactional
    def saveAndCreate(Contact contact)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (contact == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (contact.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond contact.errors, model: [user: user], view: 'create'
            return
        }

        contact.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'contact.label',
                                                                                        default: 'Contact'), contact
                    .id])
                // redirect contact
                redirect action: "create"
            }
            '*' { respond contact, [status: CREATED] }
        }
    }

    def edit(Contact contact)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        def targetUri = request.getHeader("referer")
        def permission = false

        TeamRole editTeamRole = TeamRole.findByName('Edit')
        ContactTeam contactTeam = ContactTeam.findByContactAndUser(contact, user)

        if (contact?.user?.id == user?.id || contactTeam?.teamRole?.id == editTeamRole?.id)
        {
            permission = true
        }
        else if (params['teamName'] == "accountTeam")
        {
            def contactPermission = AccountTeam.findByAccountAndUser(contact?.account, user)?.contactPermission
            if (contactPermission?.id == editTeamRole.id)
            {
                permission = true
            }
        }

        if (permission)
        {
            respond contact, model: [targetUri: targetUri, user: user]
        }
        else
        {
            flash.message = "没有编辑权限"
            redirect uri: request.getHeader("referer")
        }
    }

    @Transactional
    def update(Contact contact)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (contact == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (contact.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond contact.errors, model: [user: user], view: 'edit'
            return
        }

        contact.save flush: true
        subscribeService.sendSubscribe contact

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'contact.label',
                                                                                        default: 'Contact'), contact
                    .id])
                // redirect contact
                redirect uri: params['targetUri']
            }
            '*' { respond contact, [status: OK] }
        }

    }

    @Transactional
    def delete(Contact contact)
    {
        if (contact == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        contact.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'contact.label',
                                                                                        default: 'Contact'), contact
                    .id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'contact.label',
                                                                                          default: 'Contact'), params
                    .id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    def searchContact()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def fullName = params["fullName"]
        String sql = "from Contact as u where 1=1 and u.user.username = '${username}'"
        if (fullName)
        {
            sql += " and u.fullName like '%${fullName}%'"
        }
        String countSql = "select count(u.id) " + sql
        sql += ' order by modifiedDate desc'

        def list = Contact.findAll(sql, [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Contact.executeQuery(countSql)

        respond list, model: [contactCount: count[0], params: params], view: 'index'
    }

    def exportContact()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def fullName = params["fullName"]
        String sql = "from Contact as u where 1=1 and u.user.username = '${username}'"
        if (fullName)
        {
            sql += " and u.fullName like '%${fullName}%'"
        }
        String countSql = "select count(u.id) " + sql
        sql += ' order by modifiedDate desc'

        def list = Contact.findAll(sql)
        def count = Contact.executeQuery(countSql)

        if (params?.f && params.f != "html")
        {
            response.contentType = grailsApplication.config.grails.mime.types[params.f]
            response.setHeader("Content-disposition", "attachment; filename=contact.${params.extension}")
            List fields = ["fullName", "user.fullName", "salutation.name", "title", "job", "email", "fax", "phone", "cellphone", "wechat", "qq", "birthday", "hometown", "hobby", "taboo", "country.name", "city.name", "idNumber", "maritalStatus", "gender", "source.name", "cellphoneHasVerified", "active", "account.name", "lead.fullName", "type.name", "level.name", "hireDate", "leaveDate", "createdDate", "modifiedDate"]
            Map labels = ["fullName": "姓名", "user.fullName": "所有者", "salutation.name": "称谓", "title": "头衔", "job": "职务", "email": "邮箱", "fax": "传真", "phone": "座机", , "cellphone": "手机", "wechat": "微信", "qq": "QQ", "birthday": "生日", "hometown": "家乡", "hobby": "爱好", "taboo": "禁忌", "country.name": "国籍", "city.name": "城市", "idNumber": "身份证号", "maritalStatus": "婚姻状况", "gender": "性别", "source.name": "联系人来源", "cellphoneHasVerified": "手机已验证", "active": "是否激活", "account.name": "客户", "lead.fullName": "线索", "type.name": "联系人类型", "level.name": "联系人分级", "hireDate": "入职时间", "leaveDate": "离职时间", "createdDate": "创建时间", "modifiedDate": "修改时间"]
            exportService.export(params.f, response.outputStream, list, fields, labels, [:], [:])
        }
    }

    def visitingFrequency()
    {
        def username = springSecurityService?.getPrincipal()?.username

        def year = params["year"]
        def month = params["month"]
        def level = params["level"]

        Calendar cal = Calendar.getInstance()
        cal.set(Calendar.HOUR_OF_DAY, 0)
        if (year?.size() == 4)
        {
            cal.set(Calendar.YEAR, year.toInteger())
        }
        if (month?.size() == 2)
        {
            cal.set(Calendar.MONTH, month.toInteger() - 1)
        }
        cal.set(Calendar.DAY_OF_MONTH, 1)
        // cal.set(Calendar.HOUR, 0)
        cal.set(Calendar.MINUTE, 0)
        cal.set(Calendar.SECOND, 0)
        def firstDay = cal.getTime()

        cal = Calendar.getInstance()
        cal.set(Calendar.HOUR_OF_DAY, 23)
        if (year?.size() == 4)
        {
            cal.set(Calendar.YEAR, year.toInteger())
        }
        if (month?.size() == 2)
        {
            cal.set(Calendar.MONTH, month.toInteger() - 1)
        }
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE))
        // cal.set(Calendar.HOUR, 0)
        cal.set(Calendar.MINUTE, 59)
        cal.set(Calendar.SECOND, 59)
        def lastDay = cal.getTime()

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

        println "first day is ${format.format(firstDay)}"
        println "last day is ${format.format(lastDay)}"

        def count
        def contactList = []
        def contactList1 = []

        if (level)
        {
            contactList1 = Contact.findAllByUserAndLevel(User.findByUsername(username), ContactLevel.findByName(level), [max: params.max ?: 10, offset: params.offset ?: 0])
            count = Contact.executeQuery("select count(id) from Contact where user.username = :username and level.name = :level", [username: username, level: level])
        }
        else
        {
            contactList1 = Contact.findAllByUser(User.findByUsername(username), [max: params.max ?: 10, offset: params.offset ?: 0])
            count = Contact.executeQuery("select count(id) from Contact where user.username = :username", [username: username])
        }
        contactList1?.each {
            def itemCount

            itemCount = Activity.executeQuery("select count(a.id) from Activity a where a.contact.id = :contact and a.startTime >= :firstDay and a.endTime <= :lastDay and a.status = '已完成' group by a.contact", [contact: it?.id, firstDay: firstDay, lastDay: lastDay])

            def listItem = [:]
            listItem['id'] = it?.id
            listItem['fullName'] = it?.fullName
            listItem['level'] = it?.level
            listItem['standardCallFrequency'] = it?.level?.standardCallFrequency
            listItem['actualCallFrequency'] = itemCount[0] ?: 0
            if (listItem['standardCallFrequency'])
            {
                listItem['comletionRate'] = (listItem['actualCallFrequency'] / listItem['standardCallFrequency'] * 100)?.setScale(2, BigDecimal.ROUND_HALF_UP) + "%"
            }
            else
            {
                listItem['comletionRate'] = (0 / 100 * 100)?.setScale(2, BigDecimal.ROUND_HALF_UP) + "%"
            }
            listItem['account'] = it?.account
            listItem['user'] = it?.user
            listItem['createBy'] = it?.createBy
            listItem['modifyBy'] = it?.modifyBy
            listItem['createdDate'] = it?.createdDate
            listItem['modifiedDate'] = it?.modifiedDate

            contactList.add(listItem)
        }

        respond contactList, model: [contactCount: count[0], contactList: contactList, params: params], view: 'visitingFrequency'
    }
}
